{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Target Scaling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.random.uniform(low=5, high=20, size=100)\n",
    "e = np.random.normal(loc=0, scale=0.5, size=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = (x + e) ** 3 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/tarek/anaconda3/envs/scikitbook/lib/python3.6/site-packages/ipykernel_launcher.py:10: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.\n",
      "  # Remove the CWD from sys.path while we load stuff.\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 1, figsize=(10, 8))\n",
    "\n",
    "pd.DataFrame({'x': x, 'y': y}).plot(\n",
    "    title='Y is non-linear',\n",
    "    kind='scatter',\n",
    "    x='x', y='y', \n",
    "    color='k', ax=ax\n",
    ")\n",
    "\n",
    "fig.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = x.reshape((x.shape[0],1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import Ridge\n",
    "\n",
    "rgs = Ridge()\n",
    "rgs.fit(x_train, y_train)\n",
    "y_pred = rgs.predict(x_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MAE=704, R2=0.883232\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import mean_absolute_error\n",
    "from sklearn.metrics import r2_score\n",
    "\n",
    "print(\n",
    "    'MAE={:.0f}, R2={:2f}'.format(\n",
    "        mean_absolute_error(y_test, y_pred),\n",
    "        r2_score(y_test, y_pred),\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "class YTransformer:\n",
    "    \n",
    "    def __init__(self, power=1):\n",
    "        self.power = power\n",
    "        \n",
    "    def fit(self, x, y):\n",
    "        pass\n",
    "    \n",
    "    def transform(self, x, y):\n",
    "        return x, np.power(y, self.power)\n",
    "    \n",
    "    def inverse_transform(self, x, y):\n",
    "        return x, np.power(y, 1/self.power)\n",
    "    \n",
    "    \n",
    "    def fit_transform(self, x, y):\n",
    "        return self.transform(x, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Trasfomed y^1.00: MAE=704, R2=0.88\n",
      "Trasfomed y^0.50: MAE=378, R2=0.96\n",
      "Trasfomed y^0.33: MAE=339, R2=0.96\n",
      "Trasfomed y^0.25: MAE=359, R2=0.95\n",
      "Trasfomed y^0.20: MAE=400, R2=0.93\n"
     ]
    }
   ],
   "source": [
    "from sklearn.linear_model import Ridge\n",
    "from sklearn.metrics import mean_absolute_error\n",
    "from sklearn.metrics import r2_score\n",
    "\n",
    "for power in [1, 1/2, 1/3, 1/4, 1/5]:\n",
    "\n",
    "    yt = YTransformer(power)\n",
    "    _, y_train_t = yt.fit_transform(None, y_train)\n",
    "    _, y_test_t = yt.transform(None, y_test)\n",
    "    \n",
    "    rgs = Ridge()\n",
    "\n",
    "    rgs.fit(x_train, y_train_t)\n",
    "    y_pred_t = rgs.predict(x_test)\n",
    "    \n",
    "    _, y_pred = yt.inverse_transform(None, y_pred_t)\n",
    "\n",
    "    print(\n",
    "        'Trasfomed y^{:.2f}: MAE={:.0f}, R2={:.2f}'.format(\n",
    "            power,\n",
    "            mean_absolute_error(y_test, y_pred),\n",
    "            r2_score(y_test, y_pred),\n",
    "        )\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
